
#include <iostream>
#include <stdlib.h>

#include "Buddy.hpp"

Buddy<sizeof(LinkedList2Node<UINT8>),5> buddy;
LinkedList2Node<UINT8> *pages;
unsigned bitmap;

char textBuffer[36];

char *unsigned2Bin(unsigned n){
	unsigned mask = 1;
	for(unsigned i=0; i<32; i++, mask<<=1) textBuffer[i] = (n & mask) != 0 ? '1' : '0';
	return textBuffer;
}

bool isFree(void *addr){
	ULONG n = (reinterpret_cast<ULONG>(addr) -
			reinterpret_cast<ULONG>(pages)) /
			sizeof(LinkedList2Node<UINT8>);
	if(n > 32) return false;
	return (bitmap & (1 << n)) == 0;
}

bool setBusy(void *addr, UnsignedInteger numPages){
	ULONG n = (reinterpret_cast<ULONG>(addr) -
			reinterpret_cast<ULONG>(pages)) /
			sizeof(LinkedList2Node<UINT8>);
	for(n = 1 << n; numPages > 0; --numPages, n <<= 1) bitmap |= n;
	return true;
}

bool setFree(void *addr, UnsignedInteger numPages){
	ULONG n = (reinterpret_cast<ULONG>(addr) -
			reinterpret_cast<ULONG>(pages)) /
			sizeof(LinkedList2Node<UINT8>);
	for(n = 1 << n; numPages > 0; --numPages, n <<= 1) bitmap &= ~n;
	return true;
}

int main(){
	void* areas[4];
	
	std::cout << sizeof(LinkedList2Node<UINT8>) << std::endl;
	
	pages = (LinkedList2Node<UINT8>*)malloc(sizeof(LinkedList2Node<UINT8>)*32);
	pages[0].initialize(5);
	
	std::cout << pages << std::endl;
	
	buddy.emptyAreas[5].addNodeToFirst(pages);
	bitmap = 0;
	
	buddy.isFree = isFree;
	buddy.setBusy = setBusy;
	buddy.setFree = setFree;
	
	std::cout << (areas[0] = buddy.getPages(1)) << '\t';
	std::cout << unsigned2Bin(bitmap) << std::endl;
	std::cout << (areas[1] = buddy.getPages(10)) << '\t';
	std::cout << unsigned2Bin(bitmap) << std::endl;
	std::cout << (areas[2] = buddy.getPages(1)) << '\t';
	std::cout << unsigned2Bin(bitmap) << std::endl;
	
	buddy.returnPages(areas[2], 0);
	std::cout << unsigned2Bin(bitmap) << std::endl;
	buddy.returnPages(areas[0], 0);
	std::cout << unsigned2Bin(bitmap) << std::endl;
	buddy.returnPages(areas[1], 4);
	std::cout << unsigned2Bin(bitmap) << std::endl;
	
	return 0;
}
